package com.valuablecode.test;

import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * Knows how to create a TimeSpecification from a string time specification.
 */
class TimeSpecification {
    
    private final static Pattern reTimeSpecification = 
        Pattern.compile("(\\d{1,2})(?::(\\d{2})){0,1}(?::(\\d{2})){0,1}");

    private final Integer hours;
    private final Integer minutes;
    private final Integer seconds;

    public static TimeSpecification parse(String timeSpecification) {
        Matcher m = reTimeSpecification.matcher(timeSpecification);
        
        if (m.matches()) {
            return new TimeSpecification(asInt(m, 1), asInt(m, 2), asInt(m, 3));
        }
        
        throw new TimeSpecificationException("Invalid time specification: " + timeSpecification);
    }

    private static int asInt(Matcher m, int groupIndex) {
        return null == m.group(groupIndex) ? 0 : Integer.parseInt(m.group(groupIndex));
    }

    public TimeSpecification(int hours, int minutes, int seconds) {
        verifyHours(hours);
        verifyMinutes(minutes);
        verifySeconds(seconds);
        
        this.hours = hours;
        this.minutes = minutes;
        this.seconds = seconds;
    }

    private void verifyHours(int hours) {
        verifyInterval(hours, 23, "hours");
    }

    private void verifyMinutes(int minutes) {
        verifyInterval(minutes, 59, "minutes");
    }

    private void verifySeconds(int seconds) {
        verifyInterval(seconds, 59, "seconds");
    }

    private void verifyInterval(int period, int maxPeriod, String periodName) {
        if (maxPeriod < period) {
            throw new TimeSpecificationException("Invalid " + periodName + ": " + Integer.toString(period));
        }
    }

    public int getHours() {
        return hours;
    }

    public int getMinutes() {
        return minutes;
    }

    public int getSeconds() {
        return seconds;
    }
    
    public String toString() {
        return String.format("%02d:%02d:%02d", hours, minutes, seconds);
    }
    
}
